package com.medium.house.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Time utility methods
 * <p/>
 * Created by Milton on 2015/8/21 at 18:53.
 */
public class TimeUtil {
    public static final String FORMAT_YMD = "yyyy-MM-dd";
    public static final String FORMAT_YM = "yyyy-MM";
    public static final String FORMAT_M = "M";
    public static final String FORMAT_YMD_HM = "yyyy-MM-dd HH:mm";
    public static final String FORMAT_MD_HM_CN = "M月dd日 HH:mm";
    public static final String FORMAT_MD_CN = "M月dd日";
    public static final String FORMAT_YMD_HMS = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_YMD_HMS_CN = "yyyy年MM月dd日 HH:mm:ss";

    public static final String FORMAT_SHORT_YMD = "yyyyMMdd";
    public static final String FORMAT_SHORT_YMD_HM = "yyyyMMdd HHmm";

    public static final String REGEX_YMD = "(19|20)\\d\\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])";
    public static final String REGEX_YMD_HM = "(19|20)\\d\\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) ([0-1][0-9]|[2][0-3]):([0-5][0-9])";
    public static final String REGEX_YMD_HMS = "(19|20)\\d\\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]) ([0-1][0-9]|[2][0-3]):([0-5][0-9]):([0-5][0-9])";

    /**
     * 使用已知的日期格式, 还原日期字符串至日期对象, 出错则返回空
     *
     * @param strDate
     * @param format
     * @return
     */
    public static Date getDate(String strDate, String format) {
        Date date = null;
        if (strDate != null && strDate.length() > 0) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                date = sdf.parse(strDate);
            } catch (Exception ex) {
            }
        }
        return date;
    }

    /**
     * Format current time with specified format, using default locale
     *
     * @param format
     * @return
     */
    public static String getStr(String format) {
        return getStr(new Date(), format, null);
    }

    /**
     * Format a date with specified format, using default locale
     *
     * @param date
     * @param format
     * @return
     */
    public static String getStr(Date date, String format) {
        return getStr(date, format, null);
    }

    /**
     * Format a date with specified format and locale
     *
     * @param date
     * @param format
     * @param locale
     * @return
     */
    public static String getStr(Date date, String format, Locale locale) {
        if (date != null) {
            SimpleDateFormat dFormat;
            if (locale != null)
                dFormat = new SimpleDateFormat(format, locale);
            else
                dFormat = new SimpleDateFormat(format);

            return dFormat.format(date);
        } else {
            return "";
        }
    }

    /**
     * 获取制定毫秒数之前的日期
     *
     * @param timeDiff
     * @return
     */
    public static String getDesignatedDate(long timeDiff, String pattenrn) {
        SimpleDateFormat format = new SimpleDateFormat(pattenrn);
        long nowTime = System.currentTimeMillis();
        long designTime = nowTime - timeDiff;
        return format.format(designTime);
    }

    /**
     * 获取前几天的日期
     */
    public static String getPrefixDate(String count, String pattenrn) {
        Calendar cal = Calendar.getInstance();
        int day = 0 - Integer.parseInt(count);
        cal.add(Calendar.DATE, day); // int amount 代表天数
        Date datNew = cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat(pattenrn);
        return format.format(datNew);
    }

    /**
     * 获取两个时间点之间的天数
     *
     * @param timeZoneOffset 标准时间与当地时间的时差, 毫秒数
     * @param from
     * @param to
     * @return
     */
    public static long getDaysDiff(int timeZoneOffset, Date from, Date to) {
        if (from == null || to == null) return 0;
        long daysFrom = (from.getTime() + timeZoneOffset) / (1000L * 3600 * 24);
        long daysTo = (to.getTime() + timeZoneOffset) / (1000L * 3600 * 24);
        return daysTo - daysFrom;
    }

    /**
     * 生成指定日期的准确开始和结束时间, 从0:00.000到23:59:999
     *
     * @param date 如果为空, 则自动获取当前时间
     * @return 包含两个时间值的数组
     */
    public static Date[] getDayRangeOfDate(Date date) {
        Date[] range = new Date[2];

        if (date == null)
            date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        setDayStart(cal);
        range[0] = cal.getTime();
        setDayEnd(cal);
        range[1] = cal.getTime();
        return range;
    }

    /**
     * 生成一系列的月份开始和结束日期
     *
     * @param offset 开始距现在的月份数
     * @param months 输入多少个月, 负数表示输出的是过去的月份
     * @return 按时间顺序排列的列表, 每个节点是一个时间数组, 包含两个时间值, 代表月份的起始和结束时间
     */
    public static List<Date[]> getDateRangeByMonth(int offset, int months) {
        List<Date[]> ranges = new ArrayList<Date[]>();
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, offset);
        if (months < 0) {
            cal.add(Calendar.MONTH, months + 1);
            months = 0 - months;
        }

        for (int i = 0; i < months; i++) {
            if (i > 0)
                cal.add(Calendar.MONTH, 1);
            Date[] range = new Date[2];
            cal.set(Calendar.DATE, 1);
            setDayStart(cal);
            range[0] = cal.getTime();

            cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
            setDayEnd(cal);
            range[1] = cal.getTime();
            ranges.add(range);
        }

        return ranges;
    }

    /**
     * 得到一天的开始时间
     *
     * @param cal 传入的Calendar实例
     */
    public static void setDayStart(Calendar cal) {
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
    }

    /**
     * 得到一天结束时间
     *
     * @param cal 传入的Calendar实例
     */
    public static void setDayEnd(Calendar cal) {
        cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE));
        cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND, cal.getActualMaximum(Calendar.MILLISECOND)-1000);
    }

    /**
     * 得到某年某月的开始时间
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getLeftBoundaryOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));
        return getDayRangeOfDate(cal.getTime())[0];
    }

    /**
     * 得到某年某月的结束时间
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getRightBoundaryOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int value = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, value);
        return getDayRangeOfDate(cal.getTime())[1];
    }

    /**
     * 获取当前月份偏移N个月后得到的月份的左边界
     *
     * @param month 月份偏移量, 负数则为往更早时间偏移, 为0则为当前月份右边界
     * @return 月份的起始日开始时间
     */
    public static Date getLeftBoundaryOfDeferredMonth(int month) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, month);
        cal.set(Calendar.DATE, 1);
        setDayStart(cal);
        return cal.getTime();
    }

    /**
     * 获取当前月份偏移N个月后得到的月份的右边界
     *
     * @param month 月份偏移量, 负数则为往更早时间偏移, 为0则为当前月份右边界
     * @return 月份的结束日结束时间
     */
    public static Date getRightBoundaryOfDeferredMonth(int month) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, month);
        cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
        setDayEnd(cal);
        return cal.getTime();
    }

    /**
     * 判断身份证号 是否大于等于18岁 小于等于65岁
     *
     * @param idCard 身份证号
     * @return
     */
    public static boolean checkIdCardAge(String idCard) {
        String birthday = "";
        if (idCard == null) {
            return false;
        } else if (idCard.length() != 15 && idCard.length() != 18) {
            return false;
        }
        if (idCard.length() == 15) {
            birthday = "19" + idCard.substring(6, 12);
        } else if (idCard.length() == 18) {
            birthday = idCard.substring(6, 14);
        }
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_SHORT_YMD);
        Calendar c1 = Calendar.getInstance();
        try {
            c1.setTime(sdf.parse(birthday));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar c2 = Calendar.getInstance();
        c2.setTime(new Date());
        if (c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR) < 18) {//如果年份小于18，直接返回false，未成年
            return false;
        } else if (c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR) == 18) {//如果等于18岁
            if (c2.get(Calendar.MONTH) > c1.get(Calendar.MONTH)) { //等于18岁判断当前月份是否小于生日月份
                return false;
            } else if (c2.get(Calendar.MONTH) == c1.get(Calendar.MONTH)) {//月份等于
                if (c2.get(Calendar.DATE) > c1.get(Calendar.DATE)) {//判断生日日期是否大于当前日期
                    return false;
                }
            }
        } else if (c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR) > 65) {
            return false;
        }
        return true;
    }

    public static void main(String[] args) {
        Date date=getDate("20160803125612","yyyyMMddHHmmss");
        System.out.println(getStr(date,"yyyyMMddHHmmss"));

    }
}
